package xian.woniuxy.b_realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.Arrays;
import java.util.List;

/**
 * @author gao
 * @time 2021/12/23 11:56:14
 */
public class MyRealm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("授权...");
        // 能进入这个方法，那一定是用户已经通过认证了！已经有身份了，所以在这个方法中，
        // 是可以获取到用户的身份的！
        Object principal = principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo a = new SimpleAuthorizationInfo();
        // 这里就可以根据用户身份的不同，来返回不同的权限！
        if ("foo".equals(principal)) {
            // 如果身份是foo，那么就根据foo这个身份来获取权限
            a.addStringPermission("user:save");
            a.addStringPermission("user:delete");
        }

        if ("bar".equals(principal)) {
            // 如果身份是foo，那么就根据bar这个身份来获取权限
            a.addStringPermission("user:delete");
            a.addStringPermission("user:update");
        }

        return a;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("认证...");
        // 获取令牌中封装的账号
        String username = (String) token.getPrincipal();
        // 获取令牌中封装的密码
        String password = new String((char[]) token.getCredentials());


        // 这等价于以下sql的作用：
        // 1. 该sql能判断，账户是否存在，如果根据用户传来的username查询不到任何密码，则说明没有这个账户！
        // 2. 如果能根据账户查到密码，那这个查到的密码也只是数据库中的密码，这个密码需要和用户传来的密码比较！
        // select password from users where username = ?
        List<String> accountList = Arrays.asList("foo", "bar");
        if (!accountList.contains(username)) {
            // 当前方法如果返回null值，那么shiro框架就会认为账号找不见！
            return null;
        }


        String password2 = null;
        // selet password from users where username = 'foo'
        if ("foo".equals(username)) {
            password2 = "123";
        }
        // selet password from users where username = 'bar'
        if ("bar".equals(username)) {
            password2 = "456";
        }

        // Realm应该只返回提前存好和密码的信息！Realm把密码返回给上级 “认证器”， 认证器中“风云际会”，拿着
        // 用户的密码，与Realm返回的密码比较，该咋比就咋比！

        // 一般，我们就以用户的账户作为身份！
        return new SimpleAuthenticationInfo(username, password2, "myRealm");
    }
}
